package com.egao.common.module.company.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.egao.common.component.elasticsearch.entity.ElasticSearchConstants;
import com.egao.common.component.elasticsearch.service.ElasticSearchService;
import com.egao.common.core.exception.BusinessException;
import com.egao.common.core.exception.ParameterException;
import com.egao.common.core.web.JsonResult;
import com.egao.common.core.web.PageParam;
import com.egao.common.module.company.constants.*;
import com.egao.common.module.company.entity.*;
import com.egao.common.module.company.entity.vo.*;
import com.egao.common.module.company.mapper.MutualMapper;
import com.egao.common.module.company.service.*;
import com.egao.common.module.company.utils.CompanyUtil;
import com.egao.common.module.system.constants.EmailConstants;
import com.egao.common.module.system.entity.User;
import com.egao.common.module.system.service.EmailService;
import com.egao.common.module.system.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;

/**
 * 双选会(Mutual)表服务实现类
 *
 * @author dl
 * @since 2021-02-24 13:52:35
 */
@Service("mutualService")
public class MutualServiceImpl extends ServiceImpl<MutualMapper, Mutual> implements MutualService {

    @Autowired
    private MutualApplyService mutualApplyService;

    @Autowired
    private EmailService emailService;

    @Autowired
    private CompanyCheckRecordService companyCheckRecordService;

    @Autowired
    private AttachmentService attachmentService;

    @Autowired
    private ElasticSearchService elasticSearchService;
    @Autowired
    private CompanyService companyService;
    @Autowired
    private UserService userService;

    @Override
    public List<MutualListVO> listPage(PageParam<MutualListVO> page) {
        page = (PageParam<MutualListVO>) CompanyUtil.putApplyTime(page);
        return baseMapper.listPage(page);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public JsonResult saveMutual(MutualFormVO mutualFormVO) {
        verifyMutual(mutualFormVO);

        // 判断报名截止时间不能大于举办时间
        if (mutualFormVO.getStartTime().before(mutualFormVO.getEndTime())) {
            return JsonResult.error("报名截止时间不能大于举办时间");
        }
        Mutual mutual = new Mutual();
        BeanUtil.copyProperties(mutualFormVO, mutual);

        if (save(mutual)) {
            attachmentService.saveAttach(mutualFormVO.getAttachments(), mutual.getId(), AttachmentConstants.TYPE_MUTUAL);

            // 保存es
            String id = ElasticSearchConstants.INFORMATION_MUTUAL + "-" + mutual.getId();
            elasticSearchService.delete(ElasticSearchConstants.INDEX_NAME_INFORMATION, id);
            elasticSearchService.save(mutual);
            return JsonResult.ok("提交成功");
        }
        return JsonResult.error("提交失败");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public JsonResult checkMutual(MutualApplyFormVO mutualApplyFormVO) {
        if (mutualApplyFormVO == null) {
            throw new ParameterException("双选会报名信息为空");
        }

        if (mutualApplyFormVO.getId() == null) {
            throw new ParameterException("双选会报名信息为空");
        }

        MutualApply mutualApply = mutualApplyService.getById(mutualApplyFormVO.getId());

        if (mutualApply == null) {
            throw new BusinessException("双选会报名信息无法查询");
        }

        Mutual mutual = getById(mutualApply.getMutualId());
        if (mutualApply == null) {
            throw new BusinessException("双选会信息无法查询");
        }

        // 记录之前审核状态
        String oldState = mutualApply.getState();
        int overNumber = getCheckPassNumber(mutual.getId());
        if (MutualConstants.STATE_DSH.equals(oldState) && MutualConstants.STATE_TG.equals(mutualApplyFormVO.getState()) && mutual.getCompanyNumber() == overNumber) {
            return JsonResult.error("报名人数已满，审核需要修改报名人数");
        }

        if (MutualConstants.STATE_WTG.equals(oldState) && MutualConstants.STATE_TG.equals(mutualApplyFormVO.getState()) && mutual.getCompanyNumber() == overNumber) {
            return JsonResult.error("报名人数已满，审核需要修改报名人数");
        }

        boolean plateFlag = true;
        // 如果之前的审核状态未审核通过，并修改的状态为审核通过，不获取号牌
        if (MutualConstants.STATE_TG.equals(oldState) && MutualConstants.STATE_TG.equals(mutualApplyFormVO.getState())) {
            plateFlag = false;
        }

        BeanUtil.copyProperties(mutualApplyFormVO, mutualApply);

        // 审核通过
        if (plateFlag && MutualConstants.STATE_TG.equals(mutualApply.getState())) {
            int numberPlate = getMutualNumberPlate(mutualApply.getMutualId());
            mutualApply.setNumberPlate(numberPlate);
        }

        if (mutualApplyService.updateById(mutualApply)) {
            //需要发送邮件通知
            if(CompanyConstants.SUCCESS.equals(mutualApplyFormVO.getEmailFlag())) {
                //发送邮件
                Company company = companyService.getById(mutualApply.getCompanyId());
                if (company != null) {
                    User user = userService.getById(company.getUserId());
                    if (user != null) {
                        String[] email = {user.getUsername()};
                        emailService.sendTextEmail(EmailConstants.TITLE_MUTUAL_CHECK, mutualApplyFormVO.getStateContent(), email);
                    }
                }
            }

            CompanyCheckRecord companyCheckRecord = new CompanyCheckRecord();
            companyCheckRecord.setCompanyId(mutualApply.getCompanyId());
            companyCheckRecord.setState(mutualApply.getState());
            companyCheckRecord.setStateContent(mutualApply.getStateContent());
            companyCheckRecord.setCheckUserId(mutualApplyFormVO.getCheckUserId());
            companyCheckRecord.setType(CheckRecordConstants.CHECK_MUTUAL);
            companyCheckRecord.setBusinessId(mutualApply.getId());
            companyCheckRecordService.save(companyCheckRecord);

            return JsonResult.ok("提交成功");
        }
        return JsonResult.error("提交失败");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public JsonResult deleteMutual(MutualFormVO mutualFormVO) {
        verifyMutual(mutualFormVO);

        if (mutualFormVO.getId() == null) {
            throw new ParameterException("双选会信息编号为空");
        }

        Mutual mutual = getById(mutualFormVO.getId());
        if (mutual == null) {
            throw new BusinessException("双选会信息为空");
        }

        if (removeById(mutual)) {
            mutualApplyService.remove(new QueryWrapper<MutualApply>().eq("mutual_id", mutual.getId()));
            attachmentService.deleteAttach(mutual.getId(), AttachmentConstants.TYPE_MUTUAL);
            String id = ElasticSearchConstants.INFORMATION_MUTUAL + "-" + mutual.getId();
            elasticSearchService.delete(ElasticSearchConstants.INDEX_NAME_INFORMATION, id);
            return JsonResult.ok("删除成功");
        }
        return JsonResult.error("删除失败");
    }

    @Override
    public JsonResult detail(Integer id) {
        if (id == null) {
            throw new ParameterException("双选会信息编号为空");
        }

        Mutual mutual = getById(id);
        if (mutual == null) {
            throw new BusinessException("双选会信息为空");
        }

        MutualFormVO mutualFormVO = new MutualFormVO();
        BeanUtil.copyProperties(mutual, mutualFormVO);

        List<MutualApply> list = mutualApplyService.list(new QueryWrapper<MutualApply>().eq("mutual_id", id).eq("state", MutualConstants.STATE_TG));

        // 查询发布的附件
        List<Attachment> attachments = attachmentService.getAttachByBusinessId(id, AttachmentConstants.TYPE_MUTUAL);
        if (attachments != null && attachments.size() > 0) {
            mutualFormVO.setAttachments(attachments);
        }

        if (list != null && list.size() > 0) {
            mutualFormVO.setMutualApplyList(list);
        }
        return JsonResult.ok("查询成功").setData(mutualFormVO);
    }

    @Override
    public JsonResult updateMutual(MutualFormVO mutualFormVO) {
        verifyMutual(mutualFormVO);

        if (mutualFormVO.getId() == null) {
            throw new ParameterException("双选会信息编号为空");
        }

        Mutual mutual = getById(mutualFormVO.getId());
        if (mutual == null) {
            throw new BusinessException("双选会信息为空");
        }
        // 判断报名截止时间不能大于举办时间
        if (mutualFormVO.getStartTime().before(mutualFormVO.getEndTime())) {
            return JsonResult.error("报名截止时间不能大于举办时间");
        }
        BeanUtil.copyProperties(mutualFormVO, mutual);

        if (updateById(mutual)) {
            attachmentService.deleteAttach(mutual.getId(), AttachmentConstants.TYPE_MUTUAL);
            attachmentService.saveAttach(mutualFormVO.getAttachments(), mutual.getId(), AttachmentConstants.TYPE_MUTUAL);

            attachmentService.deleteAttach(mutual.getId(), AttachmentConstants.TYPE_MUTUAL);
            String id = ElasticSearchConstants.INFORMATION_MUTUAL + "-" + mutual.getId();
            elasticSearchService.delete(ElasticSearchConstants.INDEX_NAME_INFORMATION, id);
            elasticSearchService.save(mutual);
            return JsonResult.ok("修改成功");
        }
        return JsonResult.error("修改失败");
    }

    @Override
    public List<MutualApplyListVO> queryApply(PageParam<MutualListVO> pageParam) {
        return baseMapper.queryApply(pageParam);
    }

    @Override
    public JsonResult queryCancelApply(PageParam<MutualListVO> pageParam) {
        pageParam.setSize(-1);
        return JsonResult.ok("查询成功").setData(baseMapper.queryCancelApply(pageParam));
    }

    /** 
     * 根据号牌发放情况获取号牌
     * @date 2021/2/24 15:14
     * @param mutualId 双选会编号
     * @return 号牌
     */
    private int getMutualNumberPlate(Integer mutualId) {
        // 取消且有号牌
        List<MutualApply> list = mutualApplyService.list(new QueryWrapper<MutualApply>()
                .eq("mutual_id" ,mutualId)
                .eq("invalid", MutualConstants.INVALID_YES)
                .isNotNull("number_plate")
                .orderByAsc("number_plate"));
        if (list.size() > 0) {
            MutualApply mutualApply = list.get(0);
            int numberPlate = mutualApply.getNumberPlate();

            UpdateWrapper<MutualApply> uw = new UpdateWrapper<>();
            uw.set("number_plate", null);
            uw.lambda().eq(MutualApply::getId, mutualApply.getId());
            mutualApplyService.update(uw);

            return numberPlate;
        } else {
            Integer count = getCheckPassNumber(mutualId);
            return count + 1;
        }
    }

    /**
     * 审核通过数据
     * @param mutualId 双选会
     * @return
     */
    private int getCheckPassNumber(Integer mutualId) {
        return mutualApplyService.count(new QueryWrapper<MutualApply>()
                .isNotNull("number_plate")
                .eq("mutual_id" ,mutualId)
                .eq("state", MutualConstants.STATE_TG)
                .eq("invalid", MutualConstants.INVALID_NO));
    }

    /**
     * 验证双选会表单是否为空
     * @param mutualFormVO 宣讲会表单
     * @return
     */
    private void verifyMutual(MutualFormVO mutualFormVO) {
        if (mutualFormVO == null) {
            throw new ParameterException("双选会信息为空");
        }
    }
}